#pragma once
#ifndef __BASIC_HPP__
#define __BASIC_HPP__

#include "basic.h"
#include <functional>

namespace selfHandler
{

    template <typename F>
    void period_executor(const char *name, uint16_t period_ms, F &&func) /*use the template to separate the task*/
    {
        static uint32_t last_time = 0;
        uint32_t current_time = get_ms();
        uint32_t dt_ms = current_time - last_time;

        if (dt_ms >= period_ms)
        {
            func(dt_ms);
            last_time = current_time;
        }
    }

    class MyPrint
    {
    private:
        uint8_t float_precision;
        MyPrint();

        MyPrint(const MyPrint &) = delete;
        MyPrint &operator=(const MyPrint &) = delete;

    public:
        static MyPrint &instance();

        MyPrint &set_precision(uint8_t prec);

        MyPrint &operator<<(const char *str);
        MyPrint &operator<<(const char ch);
        MyPrint &operator<<(int64_t value);
        MyPrint &operator<<(int32_t value);
        MyPrint &operator<<(int value);
        MyPrint &operator<<(int8_t value);
        MyPrint &operator<<(uint64_t value);
        MyPrint &operator<<(uint32_t value);
        MyPrint &operator<<(uint16_t value);
        MyPrint &operator<<(uint8_t value);
        MyPrint &operator<<(float value);
        MyPrint &operator<<(bool value);
        MyPrint &operator<<(MyPrint &(*manip)(MyPrint &));
    };

    MyPrint &endl(MyPrint &mp);
    extern MyPrint &cout;
}

#endif // __BASIC_HPP__